package com.hunttown.mes.manage.controller._mes;

import com.hunttown.mes.common.OperateCode;
import com.hunttown.mes.common.utils.StringUtils;
import com.hunttown.mes.manage.controller.common.AdminBaseClass;
import com.hunttown.mes.manage.controller.common.ModelService;
import com.hunttown.mes.rpc.domain.*;
import com.hunttown.mes.rpc.domain.query.MesSaleExpressDTOQuery;
import com.hunttown.mes.rpc.domain.query.MesSaleExpressDetailDTOQuery;
import com.hunttown.mes.rpc.domain.query.MesSaleOrderDetailDTOQuery;
import com.hunttown.common.domain.Page;
import com.hunttown.mes.common.utils.DateConvertUtils;
import com.hunttown.mes.common.utils.JSONUtils;
import com.hunttown.mes.manage.service.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.*;

import static com.hunttown.mes.common.utils.PageUtils.PagePackage;

/**
 * created by wangjunfu on 2022-07-18 10:52:21
 */
@Controller
@RequestMapping(value = "/mes/order-express")
public class MesSaleExpressController {

    private final static Logger logger = LoggerFactory.getLogger(MesSaleExpressController.class);

    private final MesSaleExpressManageService mesSaleExpressService;
    private final MesSaleExpressDetailManageService expressDetailService;
    private final MesSaleOrderManageService mesSaleOrderService;
    private final MesSaleOrderDetailManageService saleOrderDetailService;
    private final AnalysisManageManageService manageService;
    private final ModelService modelService;

    @Autowired
    public MesSaleExpressController(MesSaleExpressManageService mesSaleExpressService, MesSaleExpressDetailManageService expressDetailService, MesSaleOrderManageService mesSaleOrderService, MesSaleOrderDetailManageService saleOrderDetailService, AnalysisManageManageService manageService, ModelService modelService) {
        this.mesSaleExpressService = mesSaleExpressService;
        this.expressDetailService = expressDetailService;
        this.mesSaleOrderService = mesSaleOrderService;
        this.saleOrderDetailService = saleOrderDetailService;
        this.manageService = manageService;
        this.modelService = modelService;
    }

    //region 数据列表

    /**
     * 首页
     *
     * @param model    model模型
     * @param dtoQuery 查询条件
     * @return model
     */
    @RequestMapping(value = "/index", method = RequestMethod.GET)
    public String index(Model model, MesSaleExpressDTOQuery dtoQuery) {

        //获取销售订单
        MesSaleOrderDTO orderObj = mesSaleOrderService.getById(dtoQuery.getOrderId());
        if (orderObj == null) {
            throw new RuntimeException("未查询到销售订单信息");
        }
        model.addAttribute("orderObj", orderObj);

        dtoQuery.setOrderBy("order by id desc");
        Page<MesSaleExpressDTO> dataPage = mesSaleExpressService.getForPage(dtoQuery);

        for (MesSaleExpressDTO item : dataPage.getItems()) {
            String addr = modelService.getRegionName(item.getReceiveProvince());
            addr += "," + modelService.getRegionName(item.getReceiveCity());
            addr += "," + modelService.getRegionName(item.getReceiveTown());
            item.setReceiveAddress(addr + "," + item.getReceiveAddress());

            item.setExpressName(modelService.getCatalogName(item.getExpressId()));
        }

        model.addAttribute("page", dataPage);
        model.addAttribute("PagePackage", PagePackage(dataPage.getPn(), dataPage.getStart(), dataPage.getPageSize(), dataPage.getTotalPages(), dataPage.getTotalItems()));
        model.addAttribute("dtoQuery", dtoQuery);

        return "mes/order-express/index";
    }

    //展示所有发货记录
    @RequestMapping(value = "/indexList", method = RequestMethod.GET)
    public String indexList(Model model, MesSaleExpressDTOQuery dtoQuery) {

        dtoQuery.setOrderBy("order by id desc");
        Page<MesSaleExpressDTO> dataPage = mesSaleExpressService.getForPage(dtoQuery);

        for (MesSaleExpressDTO item : dataPage.getItems()) {
            //销售订单
            MesSaleOrderDTO order = mesSaleOrderService.getFromCacheId(item.getOrderId());
            if (order != null) {
                item.setOrderTitle(order.getOrderTitle());
            }

            //收货地址
            String province = modelService.getRegionName(item.getReceiveProvince());
            String city = modelService.getRegionName(item.getReceiveCity());
            String town = modelService.getRegionName(item.getReceiveTown());

            String addr = "";
            if (StringUtils.isNotBlank(province)) {
                addr = province;
            }
            if (StringUtils.isNotBlank(city)) {
                addr = addr + " " + city;
            }
            if (StringUtils.isNotBlank(town)) {
                addr = addr + " " + town;
            }
            if (StringUtils.isNotBlank(item.getReceiveAddress())) {
                addr = addr + " " + item.getReceiveAddress();
            }
            item.setReceiveAddress(addr);

            //物流公司
            item.setExpressName(modelService.getCatalogName(item.getExpressId()));
        }

        model.addAttribute("page", dataPage);
        model.addAttribute("PagePackage", PagePackage(dataPage.getPn(), dataPage.getStart(), dataPage.getPageSize(), dataPage.getTotalPages(), dataPage.getTotalItems()));
        model.addAttribute("dtoQuery", dtoQuery);

        return "mes/order-express/index-list";
    }
    //endregion

    //region 编辑&保存

    /**
     * 编辑
     *
     * @param model model模型
     * @param id    主键id
     * @return model
     */
    @RequestMapping(value = "/edit", method = RequestMethod.GET)
    public String edit(HttpServletRequest request, Model model, Integer id, Integer orderId) {
        id = (id == null ? 0 : id);

        if (orderId == null || orderId <= 0) {
            throw new RuntimeException("未查询到销售订单信息");
        }

        //获取销售订单
        MesSaleOrderDTO orderObj = mesSaleOrderService.getById(orderId);
        if (orderObj == null) {
            throw new RuntimeException("未查询到销售订单信息");
        }
        model.addAttribute("orderObj", orderObj);

        //从销售订单明细中计算
        MesSaleOrderDetailDTOQuery detailQuery = new MesSaleOrderDetailDTOQuery();
        detailQuery.setOrderId(orderId);
        detailQuery.setStopFlag(0);
        detailQuery.setPageSize(100);
        Page<MesSaleOrderDetailDTO> saleDetailPage = saleOrderDetailService.getForPage(detailQuery);

        int total_count = 0;
        for (MesSaleOrderDetailDTO item : saleDetailPage.getItems()) {
            total_count += item.getRealProduceCount();
        }

        MesSaleExpressDTO obj;

        if (id > 0) {
            obj = mesSaleExpressService.getById(id);

            //region 收货区域
            if (obj.getReceiveProvince() > 0) {
                modelService.getRegionPage(model, obj.getReceiveProvince(), "cityPage");
            }
            if (obj.getReceiveCity() > 0) {
                modelService.getRegionPage(model, obj.getReceiveCity(), "countyPage");
            }
            //endregion

            //region 获取发货明细
            MesSaleExpressDetailDTOQuery expressDetailDTOQuery = new MesSaleExpressDetailDTOQuery();
            expressDetailDTOQuery.setExpressId(id);
            expressDetailDTOQuery.setStopFlag(0);
            Page<MesSaleExpressDetailDTO> expressDetailPage = expressDetailService.getForPage(expressDetailDTOQuery);

            List<MesSaleExpressDetailDTO> expressDetailList = new ArrayList<>();
            List<Integer> productIds = new ArrayList<>();

            //有一种情况，第一次发货少选了一件产品
            for (MesSaleExpressDetailDTO item : expressDetailPage.getItems()) {
                expressDetailList.add(item);
                productIds.add(item.getProductId());
            }

            //看看有哪条产品上次没选
            for (MesSaleOrderDetailDTO item : saleDetailPage.getItems()) {
                if (productIds.contains(item.getProductId())) {
                    continue;
                }

                MesSaleExpressDetailDTO dto = new MesSaleExpressDetailDTO();
                dto.setId(0);
                dto.setExpressId(0);
                dto.setOrderId(item.getOrderId());
                dto.setProductId(item.getProductId());
                dto.setProductName(item.getProductName());
                dto.setProductCode(item.getProductCode());
                dto.setChipName(item.getChipName());
                dto.setSpecialName(item.getSpecialName());
                dto.setModalName(item.getModalName());
                dto.setUnit(item.getUnit());
                dto.setPackageMode(item.getPackageMode());
                dto.setStoreId(item.getStoreId());
                dto.setRealProduceCount(item.getRealProduceCount());
                dto.setSendCount(0);
                dto.setRemark(item.getRemark());

                expressDetailList.add(dto);
            }

            model.addAttribute("expressDetailList", expressDetailList);
            //endregion

        } else {
            obj = new MesSaleExpressDTO();
            obj.setId(0);
            obj.setOrderId(orderId);
            obj.setTotalCount(total_count);
            obj.setSendCount(total_count);
            obj.setReceiveId(orderObj.getLinkId());
            obj.setReceiveName(orderObj.getLinkName());
            obj.setReceiveMobile(orderObj.getLinkMobile());
            obj.setReceiveProvince(orderObj.getReceiveProvince());
            obj.setReceiveCity(orderObj.getReceiveCity());
            obj.setReceiveTown(orderObj.getReceiveTown());
            obj.setReceiveAddress(orderObj.getReceiveAddr());

            String pin = AdminBaseClass.getPin(request);
            AnalysisManageDTO curr_obj = manageService.getFromCachePin(pin);
            obj.setOperator(curr_obj.getId());

            obj.setOperateDate(new Date());
            obj.setSendDate(new Date());
            obj.setExpressFee(BigDecimal.ZERO);
            obj.setExpressPaytype(1);

            //region 收货区域
            if (orderObj.getReceiveProvince() > 0) {
                modelService.getRegionPage(model, orderObj.getReceiveProvince(), "cityPage");
            }
            if (orderObj.getReceiveCity() > 0) {
                modelService.getRegionPage(model, orderObj.getReceiveCity(), "countyPage");
            }
            //endregion

            //region 发货明细
            List<MesSaleExpressDetailDTO> expressDetailList = new ArrayList<>();
            for (MesSaleOrderDetailDTO item : saleDetailPage.getItems()) {
                MesSaleExpressDetailDTO dto = new MesSaleExpressDetailDTO();
                dto.setId(0);
                dto.setExpressId(0);
                dto.setOrderId(item.getOrderId());
                dto.setProductId(item.getProductId());
                dto.setProductName(item.getProductName());
                dto.setProductCode(item.getProductCode());
                dto.setChipName(item.getChipName());
                dto.setSpecialName(item.getSpecialName());
                dto.setModalName(item.getModalName());
                dto.setUnit(item.getUnit());
                dto.setPackageMode(item.getPackageMode());
                dto.setStoreId(item.getStoreId());
                dto.setRealProduceCount(item.getRealProduceCount());
                dto.setSendCount(item.getRealProduceCount());
                dto.setRemark(item.getRemark());

                //如果是多次发货，则查询还有多少货没发
                MesSaleExpressDetailDTOQuery alreadySendQuery = new MesSaleExpressDetailDTOQuery();
                alreadySendQuery.setOrderId(item.getOrderId());
                alreadySendQuery.setProductId(item.getProductId());
                alreadySendQuery.setStopFlag(0);
                Page<MesSaleExpressDetailDTO> alreadySendPage = expressDetailService.getForPage(alreadySendQuery);

                int alreadySend = 0;
                for (MesSaleExpressDetailDTO ci : alreadySendPage.getItems()) {
                    alreadySend += ci.getSendCount();
                }
                dto.setSendCount(dto.getSendCount() - alreadySend);

                expressDetailList.add(dto);
            }
            model.addAttribute("expressDetailList", expressDetailList);
            //endregion
        }

        model.addAttribute("Obj", obj);

        //经办人
        modelService.getManagerPage(model);

        //区域信息
        modelService.getRegionPage(model, 0, "provincePage");

        //物流公司
        modelService.getCatalogPage(model, 30, "expressList");

        return "mes/order-express/edit";
    }

    /**
     * 保存 ajax异步
     *
     * @param request sevelet请求
     * @param objDTO  实体类
     * @return json
     */
    @RequestMapping(value = "/saveEdit", method = RequestMethod.POST)
    @ResponseBody
    public String saveEditNotify(HttpServletRequest request, MesSaleExpressDTO objDTO) {

        // 结果返回 结果至少包含一个操作状态和一条状态信息
        String result = "";
        Map<String, String> map = new HashMap<String, String>();

        try {
            //日期
            objDTO.setSendDate(DateConvertUtils.strToDate(objDTO.getSendDateSr()));
            objDTO.setOperateDate(DateConvertUtils.strToDate(objDTO.getOperateDateSr()));

            String pin = AdminBaseClass.getPin(request);
            AnalysisManageDTO curr_obj = manageService.getFromCachePin(pin);

            if (objDTO.getId() == null || objDTO.getId() <= 0) {
                //新增
                //设置初始值
                objDTO.setAdminId(curr_obj.getId());
                objDTO.setCreateTime(new Date());
                objDTO.setStopFlag(0);
                objDTO.setDeleteFlag(0);
                objDTO.setExpressPickup(1);
                objDTO.setStatus(0);
                objDTO = mesSaleExpressService.insert(objDTO);

                if (objDTO == null || objDTO.getId() <= 0) {
                    //操作失败
                    map = OperateCode.CompositionResult(map, -1);
                    result = JSONUtils.toJSON(map);
                    return result;
                }

            } else {
                //更新
                //将不需要更新的字段设置为NULL
                Boolean isNext = mesSaleExpressService.updateInfoById(objDTO);

                if (!isNext) {
                    //操作失败
                    map = OperateCode.CompositionResult(map, -1);
                    result = JSONUtils.toJSON(map);
                    return result;
                }
            }

            //region 同时更新客户订单的状态
            MesSaleOrderDTO update = new MesSaleOrderDTO();
            update.setId(objDTO.getOrderId());
            update.setStatus(30);
            mesSaleOrderService.updateInfoById(update);
            //endregion

            //region 发货明细表.保存成功后更新
            String[] f_id = request.getParameterValues("f_id");
            String[] f_orderid = request.getParameterValues("f_orderid");
            String[] f_productid = request.getParameterValues("f_productid");
            String[] f_sendcount = request.getParameterValues("f_sendcount");
            String[] f_remark = request.getParameterValues("f_remark");

            //1. 获取已保存的发货明细
            MesSaleExpressDetailDTOQuery expressDetailDTOQuery = new MesSaleExpressDetailDTOQuery();
            expressDetailDTOQuery.setExpressId(objDTO.getId());
            expressDetailDTOQuery.setStopFlag(0);
            Page<MesSaleExpressDetailDTO> historyPage = expressDetailService.getForPage(expressDetailDTOQuery);

            //2. 保存到数据库
            if (f_id != null && f_id.length > 0) {

                List<Integer> newDetailIds = new ArrayList<>();  //提交上来的，已保存过的ID
                MesSaleOrderDetailDTO saleOrderDetailObj;
                MesSaleExpressDetailDTO insert;

                for (int i = 0; i < f_id.length; i++) {
                    int sendcount = Integer.parseInt(f_sendcount[i]);
                    if (sendcount <= 0) {
                        continue;
                    }

                    int orderid = Integer.parseInt(f_orderid[i]);
                    if (orderid <= 0) {
                        continue;
                    }

                    int productid = Integer.parseInt(f_productid[i]);
                    if (productid <= 0) {
                        continue;
                    }

                    saleOrderDetailObj = saleOrderDetailService.getByOrderIdAndProductId(orderid, productid);
                    if (saleOrderDetailObj == null) {
                        continue;
                    }

                    insert = new MesSaleExpressDetailDTO();
                    insert.setExpressId(objDTO.getId());
                    insert.setOrderId(saleOrderDetailObj.getOrderId());
                    insert.setProductId(saleOrderDetailObj.getProductId());
                    insert.setProductName(saleOrderDetailObj.getProductName());
                    insert.setProductCode(saleOrderDetailObj.getProductCode());
                    insert.setChipName(saleOrderDetailObj.getChipName());
                    insert.setSpecialName(saleOrderDetailObj.getSpecialName());
                    insert.setModalName(saleOrderDetailObj.getModalName());
                    insert.setUnit(saleOrderDetailObj.getUnit());
                    insert.setPackageMode(saleOrderDetailObj.getPackageMode());
                    insert.setStoreId(saleOrderDetailObj.getStoreId());
                    insert.setRealProduceCount(saleOrderDetailObj.getRealProduceCount());
                    insert.setSendCount(sendcount);
                    insert.setRemark(f_remark[i]);
                    insert.setAdminId(curr_obj.getId());
                    insert.setCreateTime(new Date());
                    insert.setStopFlag(0);
                    insert.setDeleteFlag(0);

                    //更新或插入
                    int id = Integer.parseInt(f_id[i]);
                    if (id > 0) {
                        //更新
                        newDetailIds.add(id);
                        insert.setId(id);
                        expressDetailService.updateInfoById(insert);
                    } else {
                        //插入
                        expressDetailService.insert(insert);
                    }
                }

                //3.不存在新列表中的则表示已经删除了
                for (MesSaleExpressDetailDTO item : historyPage.getItems()) {
                    if (!newDetailIds.contains(item.getId())) {
                        expressDetailService.delete(item.getId());
                    }
                }
            }
            //endregion

            //操作成功 结果返回
            map = OperateCode.CompositionResult(map, 1);
            result = JSONUtils.toJSON(map);
            return result;

        } catch (Exception e) {
            //清空map
            map.clear();
            map = OperateCode.CompositionResult(map, -1);
            result = JSONUtils.toJSON(map);
            return result;
        }
    }
    //endregion

    //region 删除&改变状态

    /**
     * 通过id删除 ajax异步
     *
     * @param id 记录id
     * @return json
     */
    @RequestMapping(value = "/deleteById", method = RequestMethod.POST)
    @ResponseBody
    public String deleteNotify(Integer id) {

        // 结果返回结果至少包含一个操作状态和一条状态信息
        String result = "";
        Map<String, String> map = new HashMap<String, String>();

        if (id == null || id <= 0) {
            map = OperateCode.CompositionResult(map, -10, "请选择要删除的记录！");
            result = JSONUtils.toJSON(map);
            return result;
        }

        try {
            Boolean isNext = mesSaleExpressService.delete(id);
            map = OperateCode.CompositionResult(map, isNext ? 1 : 0);
            result = JSONUtils.toJSON(map);
            return result;

        } catch (Exception e) {
            //清空map
            map.clear();
            map = OperateCode.CompositionResult(map, -1);
            result = JSONUtils.toJSON(map);
            return result;
        }
    }

    /**
     * 状态改变 ajax异步
     *
     * @param id     记录id
     * @param status 状态
     * @return json
     */
    @RequestMapping(value = "/changeFlag", method = RequestMethod.POST)
    @ResponseBody
    public String openOrStopFlag(Integer id, Integer status) {

        // 结果返回 结果至少包含一个操作状态和一条状态信息
        String result = "";
        Map<String, String> map = new HashMap<String, String>();

        try {
            Boolean isNext = mesSaleExpressService.changeState(id, status);
            map = OperateCode.CompositionResult(map, isNext ? 1 : 0);
            result = JSONUtils.toJSON(map);
            return result;

        } catch (Exception e) {
            //清空map
            map.clear();
            map = OperateCode.CompositionResult(map, -1);
            result = JSONUtils.toJSON(map);
            return result;
        }
    }
    //endregion

    //region 数据查看

    /**
     * 数据查看
     *
     * @param model     model模型
     * @param id        主键id
     * @param tableName 数据库英文表名
     * @return model
     */
    @RequestMapping(value = "/show", method = RequestMethod.POST)
    public String show(Model model, Integer id, String tableName) {
        id = (id == null ? 0 : id);

        MesSaleExpressDTO obj = new MesSaleExpressDTO();
        obj.setId(id);

        if (id > 0) {
            obj = mesSaleExpressService.getById(id);
        }
        mesSaleExpressService.assembleObjInfo(model, tableName, obj);

        return "show/show-template";
    }

    //endregion

    //region 发货单打印
    @RequestMapping(value = "/expressPrint", method = RequestMethod.GET)
    public String expressPrint(Model model, Integer id) {

        if (id == null || id <= 0) {
            throw new RuntimeException("未查询到发货单信息");
        }

        //获取发货单信息
        MesSaleExpressDTO expressObj = mesSaleExpressService.getById(id);
        if (expressObj == null) {
            throw new RuntimeException("未查询到发货单信息");
        }

        String addr = modelService.getRegionName(expressObj.getReceiveProvince());
        addr += modelService.getRegionName(expressObj.getReceiveCity());
        addr += modelService.getRegionName(expressObj.getReceiveTown());
        expressObj.setReceiveAddress(addr + expressObj.getReceiveAddress());
        model.addAttribute("expressObj", expressObj);

        //获取销售订单信息
        MesSaleOrderDTO saleOrderObj = mesSaleOrderService.getById(expressObj.getOrderId());
        if (saleOrderObj == null) {
            throw new RuntimeException("未查询到销售订单信息");
        }
        saleOrderObj.setCompanyName(modelService.getCompanyName(saleOrderObj.getCompanyId()));
        model.addAttribute("saleOrderObj", saleOrderObj);

        //销售订单明细
        //MesSaleOrderDetailDTOQuery detailQuery = new MesSaleOrderDetailDTOQuery();
        //detailQuery.setOrderId(expressObj.getOrderId());
        //detailQuery.setStopFlag(0);
        //detailQuery.setPageSize(100);
        //Page<MesSaleOrderDetailDTO> saleDetailPage = saleOrderDetailService.getForPage(detailQuery);
        //model.addAttribute("packageList", saleDetailPage.getItems());

        //发货明细
        MesSaleExpressDetailDTOQuery expressDetailDTOQuery = new MesSaleExpressDetailDTOQuery();
        expressDetailDTOQuery.setExpressId(id);
        expressDetailDTOQuery.setStopFlag(0);
        Page<MesSaleExpressDetailDTO> expressDetailPage = expressDetailService.getForPage(expressDetailDTOQuery);
        model.addAttribute("packageList", expressDetailPage.getItems());

        return "mes/order-express/express-print";
    }
    //endregion

}